﻿/*
 * KLF Headless Browser
 * Written by Kris Oye <kristianoye@gmail.com>
 * Copyright (C) 2011-2012.  All rights reserved.
 */
namespace KLF.Lib.Browser.Resources
{
    #region Using Statements

    using System;
    using System.IO;
    using System.Net;
    using KLF.Lib.Browser.DOM;
    using KLF.Lib.Browser.DOM.Interface;
    using System.Net.Cache;

    #endregion

    /// <summary>
    /// 
    /// </summary>
    public abstract class ResourceRequest
    {
        #region Constructors

        public ResourceRequest(string path, ILoadableContent target)
        {
            Target = target;
            Path = path;
        }

        #endregion

        #region Properties

        public AssignResource AssignValue { get; set; }

        public RequestContext Context { get; set; }

        public string Path { get; set; }

        public Uri ResolvedUri { get; set; }

        public event EventHandler<ResourceRequestComplete> ResouceLoaded;

        public ILoadableContent Target { get; set; }

        #endregion

        #region Methods

        public void LoadRequest()
        {
            try
            {
                ILoadableContent content = Target as ILoadableContent;
                CacheManager cache = Context.Browser.Cache;
                FileInfo cacheKey = null;

                if (content != null)
                    content.HasLoaded = true;

                WebRequest request = Context.BuildRequest();
                string responseSource = null;

                if (request is HttpWebRequest && cache != null)
                {
                    HttpWebRequest r = request as HttpWebRequest;

                    try
                    {
                        lock (cache)
                        {
                            cacheKey = cache.GetCacheKey(request);
                        }
                        if (cacheKey.Exists)
                        {
                            r.IfModifiedSince = cacheKey.CreationTimeUtc;
                        }
                    }
                    catch (Exception)
                    {
                    }
                }

                WebResponse response = null;
                try
                {
                    response = request.GetResponse();

                    if (String.IsNullOrEmpty(responseSource))
                    {
                        StreamReader reader = new StreamReader(response.GetResponseStream());
                        responseSource = reader.ReadToEnd();

                        if (response is HttpWebResponse && cache != null)
                        {
                            cache.WriteCacheEntry(cacheKey, responseSource, response);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("ResourceRequest response message: {0}", ex.Message);

                    if (request is HttpWebRequest && cache != null)
                    {
                        try
                        {
                            lock (cache)
                            {
                                responseSource = cache.LoadCacheEntry(cacheKey);
                            }
                        }
                        catch(Exception)
                        {
                        }
                    }
                }

                AssignValue(Target, responseSource ?? "");
            }
            catch (Exception ex)
            {
                Console.WriteLine("LoadRequest error: {0}; Could not load {1}", 
                    ex.Message, Context.Uri);
            }
            ResouceLoaded(this, new ResourceRequestComplete() { Request = this });
        }

        #endregion
    }
}

